home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS03.ADF
/
Xref
/
xref.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-04-02
|
13KB
|
404 lines
/*************************************************************************
NAME
xref -- make list of all words and a file and the line numbers of
their occurrences, excluding C keywords, words within
quotation marks, and words within C comment markers, unless
overridden.
USAGE
xref <input >output -k -q -c
where -k causes inclusion of C keywords
-q causes inclusion of words within quotes (")
-c causes inclusion of words within C comment markers
DESCRIPTION
A "word" is a string of letters and digits beginning with a letter.
AUTHOR Philip T. Ansteth
DATE December 6, 1985
CLIENT ANSTETH RESEARCH
P.O. Box 35882
Tulsa, Ok.
CALLED FUNCTIONS
getmem -- gets memory from system pool
LINKAGE INFORMATION
The link command from the CLI is
alink with xref.lnk
The file alink.lnk must contain:
FROM Lstartup.obj, *
df1:cs/xref.o, *
df1:cs/getword.o, *
df1:cs/getch.o, *
df1:cs/type.o, *
df1:cs/strsave.o
TO df1:cs/xref
LIBRARY lc.lib, df1:lib/amiga.lib
MAP :nil
**************************************************************************/
#include <stdio.h>
/* define a template of a struct of type tnode */
/* This type will contain info. about each word encountered */
struct tnode {
char *word; /* pointer to text string */
int count; /* number of occurrences */
int linenum; /* first line number */
struct tnode *left; /* pointer to left child */
struct tnode *right; /* pointer to right child */
struct lnode *next; /* pointer to line number list */
};
/* define a template of a struct of type lnode */
/* This type will contain line numbers */
struct lnode {
int linenum; /* line number */
struct lnode *next; /* pointer to descendent */
};
/* global values for determining when to do line feed on line number list*/
#define MAXPER 10
int lnktrl;
char *keytab[] = {
"auto",
"break",
"case",
"char",
"continue",
"default",
"do",
"double",
"else",
"entry",
"extern",
"float",
"for",
"goto",
"if",
"int",
"long",
"register",
"return",
"short",
"sizeof",
"static",
"struct",
"switch",
"typedef",
"union",
"unsigned",
"while"
};
#define NKEYS (sizeof(keytab) / sizeof(keytab[0]))
#define MAXWORD 20 /* max no. of chars in a word */
#define LETTER 'a' /* code indicating an alpha character, a-z,A-Z */
#define DIGIT '0' /* code indicating a digit, 0-9 */
int incomments=0; /*global flag indicating whether within C comment markers */
int inquotes=0; /*global flag indicating whether within quotation marks */
/* mainline */
main(argc,argv)
int argc;
char *argv[];
{
struct tnode *root, *tree(); /* root is a pointer to a structure
of type tnode; tree is a function
returning a pointer to a structure
of type tnode */
char word[MAXWORD]; /* character array for storing word */
int t; /* receives type code from getwordl */
int lnumber=1; /* line number counter */
char *s; /* command line argument receiver */
int kwords=0,quotes=0,comments=0; /* flags for command line options */
int useflag=0; /* flag stating whether this word is used */
while (--argc > 0 && (*++argv)[0] == '-') /* scan for optional flags */
for (s = argv[0]+1; *s != '\0' ; s++) /* scan for string terminator.*/
switch(*s) { /* s is initialized with*/
case 'k': /* pointer to 1st character*/
kwords = 1; /* after that pointed to by*/
break; /* argv */
case 'q':
quotes = 1;
break;
case 'c':
comments = 1;
break;
default:
printf("xref: illegal option %c\n", *s);
argc = 1; /* make sure error message will be printed */
break;
}
if (argc != 0) {/* expect argc to equal 0 at end of previous while
and argv now is address containing pointer to
last argument */
printf("Usage: xref <input >output -k -q -c\n");
exit(1);
}
root=NULL; /* first time root is NULL */
/* read each word in file and install it somewhere in the tree */
while ((t = getwordl(word,MAXWORD,&lnumber)) != EOF)
if (t == LETTER) {
useflag = 1;
/* are we excluding C keywords? */
if (kwords == 0)
if (binary(word,keytab,NKEYS) >= 0)
useflag = 0;
/* are we excluding words within quotes? */
if (quotes == 0)
if (inquotes == 1)
useflag = 0;
/* are we excluding words within comment markers? */
if (comments == 0)
if (incomments == 1)
useflag = 0;
if (useflag == 1)
root = tree(root,word,lnumber);
}
if(incomments == 1)
printf("xref: WARNING--unbalanced C comment markers\n");
if(inquotes == 1)
printf("xref: WARNING--unbalanced quotation marks\n");
treeprint(root); /* print out the tree */
}
/*************************************************************************/
/* function to install word in tree */
struct tnode *tree(p,w,lnumber) /* returns pointer to a tnode struct */
struct tnode *p; /* UPDATE pointer to tnode structure */
char *w; /* INPUT pointer to a char string containing word */
int lnumber; /* INPUT linenumber where word occurs */
{
struct tnode *talloc(); /* talloc is a function returning a pointer
to a structure of type tnode */
char *strsave(); /* strsave is a function returning a point
to a character string */
int cond; /* holds result of strcmp */
struct lnode *list(); /* function returning pointer to lnode struct*/
if (p == NULL) { /* has a new word arrived? */
p = talloc(); /* allocate space &
return pointer for a new node */
p->word = strsave(w); /* fill in word */
p->linenum = lnumber; /* fill in first line number */
p->count = 1; /* initialize counter */
p->left = p->right = p->next = NULL; /* set pointers to NULL */
}
else if ((cond = strcmp(w, p->word)) == 0) { /* is it a repeated word? */
p->count++; /* increment counter */
p->next=list(p->next,lnumber); /* install line no. at end */
}
else if (cond < 0) /* are there more to look at in left subtree? */
p->left = tree(p->left, w,lnumber); /* install it somewhere to the left */
else /* greater into right subtree */
p->right = tree(p->right,w,lnumber);
return(p); /* return pointer */
}
/*************************************************************************/
/* function to install line number at end of list */
struct lnode *list(lp,lnumber)
struct lnode *lp; /* UPDATE: pointer to lnode struct */
int lnumber; /* INPUTE: line number where word occurred */
{
struct lnode *lalloc(); /* function returning pointer to lnode struct */
if(lp == NULL) { /* is this the end of the list? */
lp = lalloc(); /* get pointer for next node */
lp->linenum = lnumber; /* install line number there */
lp->next = NULL; /* fill in NULL to end list there */
}
else
lp->next=list(lp->next,lnumber); /* go on to next node */
return(lp); /* return pointer for installation by caller */
}
/*************************************************************************/
/* function to print tree recursively,
using "left tree" order */
treeprint(p)
struct tnode *p; /* INPUT: pointer to tnode struct */
{
static int ifirst=1; /* first time flag */
if(ifirst == 1) { /* print headers on first time through */
ifirst = 0;
printf("\n");
printf("Cross Reference Utility\n\n");
printf("Count Word Lines where occurring\n\n");
}
if(p != NULL) {
treeprint(p->left); /* do left branch first */
printf("%5d %-20.20s %4d", /* print current data */
p->count,p->word,p->linenum);
lnktrl=1; /* set line no. counter to 1 */
listprint(p->next); /* print line occurrences */
treeprint(p->right); /* now do right branch */
}
}
/*************************************************************************/
/* function to print out line numbers of word occurrences */
listprint(lp)
struct lnode *lp; /* INPUT: pointer to lnode struct */
{
if(lp != NULL) {
if(lnktrl < MAXPER) {
printf(" %d",lp->linenum);
lnktrl++;
}
else {
printf("\n %d",lp->linenum);
lnktrl=1;
}
listprint(lp->next);
}
else
printf("\n");
}
/*************************************************************************/
/* function to allocate memory for tnode struct */
struct tnode *talloc() /* get memory for structure and return
pointer of the correct type */
{
char *getmem(); /* getmem is a subroutine returning
a pointer to a character */
return(
(struct tnode *) /* coerce getmem to a pointer t a tnode struct */
getmem(sizeof(struct tnode)) /* get memory for a tnode structure */
);
}
/*************************************************************************/
/* function to allocate memor∙ for lnode struct */
struct lnode *lalloc()
{
char *getmem();
return( (struct lnode *) getmem(sizeof(struct lnode)));
}
/*************************************************************************/
/* function to get next word from input */
getwordl(w,lim,plnumber) /* get next word from input */
char *w; /* OUTPUT: pointer to word found */
int lim; /* INPUT: maximum word length */
int *plnumber; /* UPDATE: line number where word found */
/* returns LETTER when word found */
/* otherwise returns most recent non-alpha char */
{
int c,t; /* receive output of getch and type functions */
if ( (c = getch()) == '"')
inquotes = !inquotes;
ungetch(c);
if (incomments == 0) {
c = getch();
t = getch();
if (c == '/' && t == '*')
incomments = 1;
ungetch(t);
ungetch(c);
}
else if (incomments == 1) {
c = getch();
t = getch();
if (c == '*' && t == '/')
incomments = 0;
ungetch(t);
ungetch(c);
}
if(type(c = *w++ = getch()) != LETTER) { /* is first character non-alpha? */
*w = '\0'; /* second character of w is string terminator */
if( c == '\n')
*plnumber += 1;
return(c); /* return character in c too */
}
while (--lim > 0) { /* check subsequent characters up to lim */
t = type(c = *w++ = getch()); /* put alpha or num. in w and t */
if (t != LETTER && t != DIGIT) {
ungetch(c);
break;
}
}
*(w-1) = '\0'; /* reached end, so back up and put in string delimiter */
return(LETTER);
}
/*************************************************************************/
binary(word,tab,n) /* find word in tab[0]. . .tab[n-1] */
char *word;
char *tab[]; /* tab is a table of pointers */
int n;
{
int cond;
int low;
int high;
int mid;
low = 0;
high = n-1;
while(low <= high) {
mid = (high+low) / 2;
if ((cond=strcmp(word,tab[mid])) < 0)
high = mid-1;
else if (cond > 0)
low = mid+1;
else
return(mid);
}
return(-1);
}